package basic;

import com.alibaba.fastjson.JSONObject;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Author G_Y
 * @Date 2021/4/1 15:49
 * @Description: // TODO
 **/
public class DepartmentTest {

    public static void main(String[] args) {
        //初始化测试数据
        List<Department> list = new ArrayList<>();
        list.add(new Department(100101, "后台开发部门", 1001));
        list.add(new Department(100102, "前台开发部门", 1001));
        list.add(new Department(100103, "测试部门", 1001));
        list.add(new Department(1001, "研发部", 10));
        list.add(new Department(1002, "财务部", 10));
        list.add(new Department(1003, "人事部", 10));
        list.add(new Department(10, "总裁办", null));
        // ...

        // 获取节点ID及其儿子们的map映射关系，方便后续使用
        HashMap<Integer, List<Department>> map = new HashMap<>();// 父节点id 及父节点下集合 map
        list.forEach(department -> {
            List<Department> departments = map.get(department.getPid());
            if (departments == null) {
                departments = new ArrayList<>();
                map.put(department.getPid(), departments);
            }
            departments.add(department);
        });

        List<Department> rootDepts = map.get(null);
        if(CollectionUtils.isEmpty(rootDepts) || rootDepts.size()>1){
            throw new RuntimeException("数据错误");
        }
        // 获取根节点
        Department department = rootDepts.get(0);
        DepartmentVO rootDept = department.parse2VO();
        // 获取完整根节点（含子项）
        DepartmentVO departmentVO = treeDeptList(rootDept, map);
//        System.out.println(departmentVO);
        System.out.println(JSONObject.toJSONString(departmentVO));
    }

     /**
      * @Author G_Y
      * @Description: 根据当前节点 递归获取其子节点并设置其中
      * @Date 2021/4/1 17:22
      * map：// 父节点id 及父节点下集合 map
      **/
    public static DepartmentVO treeDeptList(DepartmentVO departmentVO, Map<Integer, List<Department>> map) {
        Integer id = departmentVO.getId();// 当前节点id
        List<Department> sons = map.get(id);// 以当前节点id作为父节点的子节点集合
        if (sons == null) {
            // 如果不存在子节点，则不需要再操作
            return departmentVO;
        }
        // 如果存在则需要 将 字节点 加入到 当前节点的 departmentVOList 属性中
        ArrayList<DepartmentVO> departmentVOSList = new ArrayList<>();
        departmentVO.setDepartmentVOList(departmentVOSList);
        for (Department son : sons) {
            DepartmentVO sonVO = son.parse2VO();
            departmentVOSList.add(sonVO);
            sonVO = treeDeptList(sonVO, map);
        }
        return departmentVO;
    }

}
// 业务展示层实体
class DepartmentVO extends Department {
    List<DepartmentVO> departmentVOList;
    public List<DepartmentVO> getDepartmentVOList() {
        return departmentVOList;
    }
    public void setDepartmentVOList(List<DepartmentVO> departmentVOList) {
        this.departmentVOList = departmentVOList;
    }
}
// 数据库实体
class Department {
    private Integer id;
    private String name;
    private Integer pid;
    public Department() {
    }
    public DepartmentVO parse2VO() {
        DepartmentVO departmentVO = new DepartmentVO();
        departmentVO.setName(this.name);
        departmentVO.setId(this.id);
        departmentVO.setPid(this.pid);
        return departmentVO;
    }
    public Department(Integer id, String name, Integer pid) {
        this.id = id;
        this.name = name;
        this.pid = pid;
    }
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Integer getPid() {
        return pid;
    }
    public void setPid(Integer pid) {
        this.pid = pid;
    }
}